package com.inspur.edp.rule.dsl.core.function.list;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.inspur.edp.cef.entity.entity.ICefData;
import com.inspur.edp.rule.dsl.core.function.list.getter.CefDataGetter;
import com.inspur.edp.rule.dsl.core.function.list.getter.DirectGetter;
import com.inspur.edp.rule.dsl.core.function.list.getter.JsonGetter;
import com.inspur.edp.rule.dsl.core.function.list.getter.MethodGetter;

import java.util.*;

/**
 * @author lizhaorui
 * @description TODO
 * @date 2025/1/8 16:06
 */

public class ListUtils {

    public static void add(Iterable iterable, Object element) {
        if (iterable == null || element == null) {
            return;
        }
        if (iterable instanceof Collection) {
            ((Collection) iterable).add(element);
        } else if (iterable instanceof ArrayNode) {
            ((ArrayNode) iterable).add((JsonNode) element);
        } else {
            throw new IllegalArgumentException(String.format("not support collection type %s", iterable.getClass().getSimpleName()));
        }
    }

    public static void addAll(Iterable iterable, Iterable elements) {
        if (iterable == null || elements == null) {
            return;
        }
        if (iterable instanceof Collection) {
            ((Collection) iterable).addAll((Collection) elements);
        } else if (iterable instanceof ArrayNode) {
            ((ArrayNode) iterable).addAll((ArrayNode) elements);
        } else {
            throw new IllegalArgumentException(String.format("not support collection type %s", iterable.getClass().getSimpleName()));
        }
    }

    public static int size(Iterable iterable) {
        if (iterable == null) {
            return 0;
        }
        if (iterable instanceof Collection) {
            return ((Collection) iterable).size();
        } else if (iterable instanceof ArrayNode) {
            return ((ArrayNode) iterable).size();
        } else {
            throw new IllegalArgumentException(String.format("not support collection type %s", iterable.getClass().getSimpleName()));
        }
    }

    public static boolean contains(Iterable iterable, Object element) {
        if (iterable == null || element == null) {
            return false;
        }
        if (iterable instanceof Collection) {
            return ((Collection) iterable).contains(element);
        } else if (iterable instanceof ArrayNode) {
            for (Object object : iterable) {
                if (object.equals(element)) {
                    return true;
                }
            }
        } else {
            throw new IllegalArgumentException(String.format("not support collection type %s", iterable.getClass().getSimpleName()));

        }
        return false;
    }

    public static Number sumByField(Iterable iterable, String fieldName) {
        if (iterable == null) {
            return 0;
        }
        Object firstObj = null;
        for (Object object : iterable) {
            firstObj = object;
            break;
        }
        if (firstObj == null) {
            return 0;
        }
        IGetFieldValue adapter = getFieldValueAdapter(firstObj, fieldName);
        double total = 0;
        for (Object object : iterable) {
            Number number = (Number) adapter.getNumber(object);
            total += number.doubleValue();
        }
        return total;
    }

    public static void sortByField(Collection collection, String fieldName, boolean asc) {
        if (collection == null || collection.size() == 0) {
            return;
        }
        Object firstObj = collection.iterator().next();
        IGetFieldValue adapter = getFieldValueAdapter(firstObj, fieldName);
        collection.stream().sorted(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Number number1 = (Number) adapter.getNumber(o1);
                Number number2 = (Number) adapter.getNumber(o2);
                if (asc) {
                    return Double.compare(number1.doubleValue(), number2.doubleValue());
                } else {
                    return Double.compare(number2.doubleValue(), number1.doubleValue());
                }
            }
        });
    }

    public static List<String> getFieldDistinctStrings(Iterable iterable, String fieldName) {
        if (iterable == null) {
            return null;
        }
        Object firstObj = null;
        for (Object object : iterable) {
            firstObj = object;
            break;
        }
        if (firstObj == null) {
            return null;
        }
        IGetFieldValue adapter = getFieldValueAdapter(firstObj, fieldName);
        ArrayList<String> list = new ArrayList<>();
        for (Object item : iterable) {
            String itemStr = (String) adapter.getString(item);
            if (list.contains(itemStr)) {
                continue;
            } else {
                list.add(itemStr);
            }
        }
        return list;
    }

    public static List<String> getFieldStrings(Iterable iterable, String fieldName) {
        if (iterable == null) {
            return null;
        }
        Object firstObj = null;
        for (Object object : iterable) {
            firstObj = object;
            break;
        }
        if (firstObj == null) {
            return null;
        }
        IGetFieldValue adapter = getFieldValueAdapter(firstObj, fieldName);
        ArrayList<String> list = new ArrayList<>();
        for (Object item : iterable) {
            String itemStr = (String) adapter.getString(item);
            list.add(itemStr);
        }
        return list;
    }

    public static Collection subtractAll(Collection collection1, Collection collection2) {
        if (collection1 == null || collection1.size() == 0) {
            return collection1;
        }
        if (collection2 == null) {
            return collection1;
        }
        for (Object object : collection2) {
            collection1.remove(object);
        }
        return collection1;
    }

    public static Collection subtract(Collection collection1, Object object) {
        if (collection1 == null || collection1.size() == 0) {
            return collection1;
        }
        if (object == null) {
            return collection1;
        }
        collection1.remove(object);
        return collection1;
    }

    public static List<String> createStringCollection(String... strings) {
        return Arrays.asList(strings);
    }


    private static IGetFieldValue getFieldValueAdapter(Object object, String fieldName) {
        if (object instanceof ObjectNode) {
            return new JsonGetter(fieldName);
        } else if (object instanceof ICefData) {
            return new CefDataGetter(object, fieldName);
        } else if (object.getClass().getSimpleName().startsWith("BeEntity_")) {
            return new MethodGetter(object.getClass(), fieldName);
        } else {
            return new DirectGetter(object.getClass(), fieldName);
        }
    }

}
